/* $Header: list_mgmt.h,v 2.2 01/10/02 10:30:28 przybyls Exp $ */

/***********************************************************************/
/* INCLUDE FILE NAME:                                                  */
/* ==================                                                  */
/*                                                                     */
/* Author:                                                             */
/*                                                                     */
/* COMMENT:                                                            */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

#ifndef LIST_MGMT_H
#define LIST_MGMT_H

 #include <typedefs.h>  
/* #include <i_op.h>      */
/* #include <stddef.h>    */

/*****************************/
/*   IFDEFS                  */
/*****************************/


/*****************************/
/*   TYPEDEFS                */
/*****************************/

struct queue { struct queue  *Next_Entry;
               struct queue  *Prev_Entry;
             };

typedef struct queue QUEUE, *pQUEUE;



typedef struct { struct queue Queue;
                 long         Num_Entries;

               } QUEUE_HEAD, *pQUEUE_HEAD;


/*  WARNING : the file send_q.S uses hand written assembly code */
/*            to read from this structure! if you change this   */
/*            you have to modify the assembly also !            */

typedef struct { struct queue  Queue;
                 pQUEUE_HEAD   Return_Queue;
                 U_INT32       filler;
                 U_INT16       PCB_Command [16];
                 U_INT16       PCB_Response[16];
                 U_INT32       msg;

               } QUEUE_ENTRY, *pQUEUE_ENTRY;

typedef struct { struct queue Queue;
                 U_INT32      Cmd;
                 U_INT32      Parm;
               
               } GAS_TASK_MSG, *pGAS_TASK_MSG;


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/

/* queue used to send cmds from background tasks -> Gas_Task */

extern QUEUE_HEAD Gas_Task_Free_Buffers;
extern QUEUE_HEAD Gas_Task_Cmds;

#define NUM_GAS_TASK_BUFFERS   26  /* two times number of gasses in method */
extern  GAS_TASK_MSG Gas_Task_Buffers[];



/* queues used for background -> foreground cmds sent to pcb2 */

extern QUEUE_HEAD Pneu_Cmd_Queue;
extern QUEUE_HEAD Pneu_Resp_Queue;
extern QUEUE_HEAD Pneu_Free_Pool;
extern QUEUE_HEAD Keyboard_Cmd_Proc_Queue;
extern QUEUE_HEAD DataComm_Cmd_Proc_Queue;
extern QUEUE_HEAD RS_232_Cmd_Proc_Queue;
extern QUEUE_HEAD Stat_Mon_Queue;
extern QUEUE_HEAD Gas_Task_Queue;
extern QUEUE_HEAD Seq_Task_Queue;
extern QUEUE_HEAD Clk_Task_Queue;
extern QUEUE_HEAD Disp_Mon_Queue;

#define NUM_FG_BG_BUFFERS 10
extern QUEUE_ENTRY Pneu_Buffer_Pool[];
/*------------changed by wangwei-------------*/
extern pthread_mutex_t queue_mut;
extern pthread_mutex_t recvqueue_mut;


/*****************************/
/*   MACROS                  */
/*****************************/



#define UnlinkBuffer(buffer)                                                    \
                                                                                \
{                                                                               \
     pthread_mutex_lock(&queue_mut);  \
     INTERRUPTS_OFF                                                             \
     ((pQUEUE)buffer)->Prev_Entry->Next_Entry = ((pQUEUE)buffer)->Next_Entry;   \
     ((pQUEUE)buffer)->Next_Entry->Prev_Entry = ((pQUEUE)buffer)->Prev_Entry;   \
     INTERRUPTS_ON                                                              \
     pthread_mutex_unlock(&queue_mut);\
}                                                                               \



#define LinkBufferToTail(buffer,queue_head)                                     \
                                                                                \
{                                                                               \
     INTERRUPTS_OFF                                                             \
     ((pQUEUE)buffer)->Next_Entry = (pQUEUE)queue_head;                         \
     ((pQUEUE)buffer)->Prev_Entry = ((pQUEUE)queue_head)->Prev_Entry;           \
                                                                                \
     ((pQUEUE)buffer)->Prev_Entry->Next_Entry = (pQUEUE)buffer;                 \
     ((pQUEUE)queue_head)->Prev_Entry = (pQUEUE)buffer;                         \
                                                                                \
     ((pQUEUE_HEAD)queue_head)->Num_Entries++;                                  \
     INTERRUPTS_ON                                                              \
}





#define LinkBufferToHead(buffer,queue_head)                                     \
                                                                                \
{                                                                               \
     INTERRUPTS_OFF                                                             \
     ((pQUEUE)buffer)->Prev_Entry = (pQUEUE)queue_head;                         \
     ((pQUEUE)buffer)->Next_Entry = ((pQUEUE)queue_head)->Next_Entry;           \
                                                                                \
     ((pQUEUE)buffer)->Next_Entry->Prev_Entry = (pQUEUE)buffer;                 \
     ((pQUEUE)queue_head)->Next_Entry = (pQUEUE)buffer;                         \
                                                                                \
     ((pQUEUE_HEAD)queue_head)->Num_Entries++;                                  \
     INTERRUPTS_ON                                                              \
}


#define GetBuffer(buffer,queue_head)                                            \
                                                                                \
{                                                                                \
     INTERRUPTS_OFF                                                             \
     if ( ((pQUEUE_HEAD)queue_head)->Num_Entries == 0 )                         \
     {    /* no buffers available */                                            \
          buffer = NULL;                                                        \
     }                                                                          \
     else                                                                       \
     {                                                                          \
          buffer = (void *)((pQUEUE)queue_head)->Next_Entry;                    \
          ((pQUEUE)buffer)->Prev_Entry->Next_Entry = ((pQUEUE)buffer)->Next_Entry;   \
          ((pQUEUE)buffer)->Next_Entry->Prev_Entry = ((pQUEUE)buffer)->Prev_Entry;   \
          ((pQUEUE_HEAD)queue_head)->Num_Entries--;                             \
     }                                                                          \
     INTERRUPTS_ON                                                              \
}                                                                               


#define CountBuffers(queue_head,num_buffers)                                    \
                                                                                \
{                                                                               \
     INTERRUPTS_OFF                                                             \
     num_buffers = ((pQUEUE_HEAD)queue_head)->Num_Entries;                      \
     INTERRUPTS_ON                                                              \
}                                                                                

/*-----------end changed by wangwei-----------*/

/*****************************/
/*   FUNCTION PROTOTYPES     */
/*****************************/

#endif


